package com.xqq.utils;

import cn.hutool.core.io.FileUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.xqq.dao.RiskMonitoringInfoDAO;
import com.xqq.dao.WeatherInfoDAO;
import com.xqq.entity.RiskMonitoringInfoDO;
import com.xqq.entity.WeatherInfoDO;
import com.xqq.mapper.RiskMonitoringInfoMapper;
import com.xqq.mapper.WeatherInfoMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.File;
import java.nio.charset.StandardCharsets;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class WeatherJsonParser {

    @Resource
    private WeatherInfoDAO weatherInfoDAO;

    @Resource
    private RiskMonitoringInfoDAO riskMonitoringInfoDAO;


    //"F:\\Code\\Code_xwsk\\response.json"
    @Transactional
    public void parsehouly(String path, int fireId, String country) {
        System.out.println("开始。。。");
        // 读取JSON文件
        String jsonStr = FileUtil.readString(new File(path), StandardCharsets.UTF_8);
        // 解析JSON
        JSONObject json = JSONUtil.parseObj(jsonStr);
        List<JSONObject> days = json.getJSONArray("days").toList(JSONObject.class);
        List<WeatherInfoDO> weatherList = new ArrayList<>();
        List<RiskMonitoringInfoDO> riskMonitoringInfoDOList = new ArrayList<>();
        for (JSONObject day : days) {
            RiskMonitoringInfoDO riskMonitoringInfoDO = new RiskMonitoringInfoDO();
            //火险等级
            riskMonitoringInfoDO.setRiskType(1);
            riskMonitoringInfoDO.setDesDate(new Date(day.getLong("datetimeEpoch") * 1000));
            riskMonitoringInfoDO.setResult("三级");
            riskMonitoringInfoDO.setCreatedBy("system");
            riskMonitoringInfoDO.setUpdatedBy("system");
            riskMonitoringInfoDO.setUpdatedTime(new Date());
            riskMonitoringInfoDO.setCreatedTime(new Date());
            riskMonitoringInfoDO.setCounty(country);
            riskMonitoringInfoDOList.add(riskMonitoringInfoDO);
            //温度
            riskMonitoringInfoDO = new RiskMonitoringInfoDO();
            riskMonitoringInfoDO.setRiskType(3);
            riskMonitoringInfoDO.setDesDate(new Date(day.getLong("datetimeEpoch") * 1000));
            riskMonitoringInfoDO.setResult(String.valueOf(day.getDouble("temp")));
            riskMonitoringInfoDO.setMaximumTemperature(String.valueOf(day.getDouble("tempmax")));
            riskMonitoringInfoDO.setMinimumTemperature(String.valueOf(day.getDouble("tempmin")));
            riskMonitoringInfoDO.setCreatedBy("system");
            riskMonitoringInfoDO.setUpdatedBy("system");
            riskMonitoringInfoDO.setUpdatedTime(new Date());
            riskMonitoringInfoDO.setCreatedTime(new Date());
            riskMonitoringInfoDO.setCounty(country);

            riskMonitoringInfoDOList.add(riskMonitoringInfoDO);
            //气压
            riskMonitoringInfoDO = new RiskMonitoringInfoDO();
            riskMonitoringInfoDO.setRiskType(4);
            riskMonitoringInfoDO.setDesDate(new Date(day.getLong("datetimeEpoch") * 1000));
            riskMonitoringInfoDO.setResult(String.valueOf(day.getDouble("pressure")));
            riskMonitoringInfoDO.setCreatedBy("system");
            riskMonitoringInfoDO.setUpdatedBy("system");
            riskMonitoringInfoDO.setUpdatedTime(new Date());
            riskMonitoringInfoDO.setCounty(country);
            riskMonitoringInfoDO.setCreatedTime(new Date());
            riskMonitoringInfoDOList.add(riskMonitoringInfoDO);
            //湿度
            riskMonitoringInfoDO = new RiskMonitoringInfoDO();
            riskMonitoringInfoDO.setRiskType(5);
            riskMonitoringInfoDO.setDesDate(new Date(day.getLong("datetimeEpoch") * 1000));
            riskMonitoringInfoDO.setResult(String.format("%.1f", day.getDouble("humidity") / 100));
            riskMonitoringInfoDO.setCreatedBy("system");
            riskMonitoringInfoDO.setUpdatedBy("system");
            riskMonitoringInfoDO.setUpdatedTime(new Date());
            riskMonitoringInfoDO.setCounty(country);
            riskMonitoringInfoDO.setCreatedTime(new Date());
            riskMonitoringInfoDOList.add(riskMonitoringInfoDO);
            //风力
            riskMonitoringInfoDO = new RiskMonitoringInfoDO();
            riskMonitoringInfoDO.setRiskType(6);
            riskMonitoringInfoDO.setDesDate(new Date(day.getLong("datetimeEpoch") * 1000));
            riskMonitoringInfoDO.setResult(String.format("%.1f", day.getDouble("windspeed") / 3.6));
            riskMonitoringInfoDO.setCreatedBy("system");
            riskMonitoringInfoDO.setUpdatedBy("system");
            riskMonitoringInfoDO.setCounty(country);
            riskMonitoringInfoDO.setUpdatedTime(new Date());
            riskMonitoringInfoDO.setCreatedTime(new Date());
            riskMonitoringInfoDOList.add(riskMonitoringInfoDO);
            //降水
            riskMonitoringInfoDO = new RiskMonitoringInfoDO();
            riskMonitoringInfoDO.setRiskType(7);
            riskMonitoringInfoDO.setDesDate(new Date(day.getLong("datetimeEpoch") * 1000));
            riskMonitoringInfoDO.setResult(String.valueOf(day.getDouble("precip")));
            riskMonitoringInfoDO.setCreatedBy("system");
            riskMonitoringInfoDO.setUpdatedBy("system");
            riskMonitoringInfoDO.setCounty(country);
            riskMonitoringInfoDO.setUpdatedTime(new Date());
            riskMonitoringInfoDO.setCreatedTime(new Date());
            riskMonitoringInfoDOList.add(riskMonitoringInfoDO);
            //风向
            riskMonitoringInfoDO = new RiskMonitoringInfoDO();
            riskMonitoringInfoDO.setRiskType(8);
            riskMonitoringInfoDO.setDesDate(new Date(day.getLong("datetimeEpoch") * 1000));
            riskMonitoringInfoDO.setResult(convertWindDirection(day.getDouble("winddir")));
            riskMonitoringInfoDO.setCreatedBy("system");
            riskMonitoringInfoDO.setUpdatedBy("system");
            riskMonitoringInfoDO.setUpdatedTime(new Date());
            riskMonitoringInfoDO.setCounty(country);
            riskMonitoringInfoDO.setCreatedTime(new Date());
            riskMonitoringInfoDOList.add(riskMonitoringInfoDO);
            JSONArray hours = day.getJSONArray("hours");
            hours.forEach(hour -> {
                WeatherInfoDO weatherInfoDO = new WeatherInfoDO();
                JSONObject hourObj = (JSONObject) hour;
                weatherInfoDO.setFireId(fireId);
                weatherInfoDO.setRecordTime(new Date(hourObj.getLong("datetimeEpoch") * 1000));
                weatherInfoDO.setTemperature(String.valueOf(hourObj.getDouble("temp")));
                weatherInfoDO.setWindLevel(String.format("%.1f", hourObj.getDouble("windspeed") / 3.6));
                weatherInfoDO.setWindDirection(convertWindDirection(hourObj.getDouble("winddir")));
                weatherInfoDO.setPressure(String.valueOf(hourObj.getDouble("pressure")));
                weatherInfoDO.setHumidity(String.format("%.1f", hourObj.getDouble("humidity") / 100));
                //海拔先不改
                weatherInfoDO.setAltitude("15");
                weatherInfoDO.setRainfallRate(String.valueOf(hourObj.getDouble("precip")));
                weatherInfoDO.setCounty(country);
                weatherInfoDO.setDeleted(0);
                weatherInfoDO.setCreatedBy("system");
                weatherInfoDO.setUpdatedBy("system");
                weatherInfoDO.setUpdatedTime(new Date());
                weatherInfoDO.setCreatedTime(new Date());
                weatherList.add(weatherInfoDO);
            });
        }
        weatherInfoDAO.saveBatch(weatherList);
        System.out.println("成功保存" + country + " weatherInfoDAO" + weatherList.size() + "条数据。");
        riskMonitoringInfoDAO.saveBatch(riskMonitoringInfoDOList);
        System.out.println("成功保存" + country + " riskMonitoringInfoDAO" + riskMonitoringInfoDOList.size() + "条数据。");
    }

    @Transactional
    public void parseAddHourly(String path, int fireId, String country, String beginDateStr) throws ParseException {
        System.out.println("开始。。。");
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date beginDate = dateFormat.parse(beginDateStr);
        // 读取JSON文件
        String jsonStr = FileUtil.readString(new File(path), StandardCharsets.UTF_8);
        // 解析JSON
        JSONObject json = JSONUtil.parseObj(jsonStr);
        List<JSONObject> days = json.getJSONArray("days").toList(JSONObject.class);
        List<WeatherInfoDO> weatherList = new ArrayList<>();
        List<RiskMonitoringInfoDO> riskMonitoringInfoDOList = new ArrayList<>();
        for (JSONObject day : days) {
            RiskMonitoringInfoDO riskMonitoringInfoDO = new RiskMonitoringInfoDO();
            //火险等级
            riskMonitoringInfoDO.setRiskType(1);
            Date date = new Date(day.getLong("datetimeEpoch") * 1000);
            if (date.toInstant().isBefore(beginDate.toInstant())) {
                continue;
            }
            riskMonitoringInfoDO.setDesDate(new Date(day.getLong("datetimeEpoch") * 1000));
            riskMonitoringInfoDO.setResult("三级");
            riskMonitoringInfoDO.setCreatedBy("system");
            riskMonitoringInfoDO.setUpdatedBy("system");
            riskMonitoringInfoDO.setUpdatedTime(new Date());
            riskMonitoringInfoDO.setCreatedTime(new Date());
            riskMonitoringInfoDO.setCounty(country);
            riskMonitoringInfoDOList.add(riskMonitoringInfoDO);
            //温度
            riskMonitoringInfoDO = new RiskMonitoringInfoDO();
            riskMonitoringInfoDO.setRiskType(3);
            riskMonitoringInfoDO.setDesDate(new Date(day.getLong("datetimeEpoch") * 1000));
            riskMonitoringInfoDO.setResult(String.valueOf(day.getDouble("temp")));
            riskMonitoringInfoDO.setMaximumTemperature(String.valueOf(day.getDouble("tempmax")));
            riskMonitoringInfoDO.setMinimumTemperature(String.valueOf(day.getDouble("tempmin")));
            riskMonitoringInfoDO.setCreatedBy("system");
            riskMonitoringInfoDO.setUpdatedBy("system");
            riskMonitoringInfoDO.setUpdatedTime(new Date());
            riskMonitoringInfoDO.setCreatedTime(new Date());
            riskMonitoringInfoDO.setCounty(country);

            riskMonitoringInfoDOList.add(riskMonitoringInfoDO);
            //气压
            riskMonitoringInfoDO = new RiskMonitoringInfoDO();
            riskMonitoringInfoDO.setRiskType(4);
            riskMonitoringInfoDO.setDesDate(new Date(day.getLong("datetimeEpoch") * 1000));
            riskMonitoringInfoDO.setResult(String.valueOf(day.getDouble("pressure")));
            riskMonitoringInfoDO.setCreatedBy("system");
            riskMonitoringInfoDO.setUpdatedBy("system");
            riskMonitoringInfoDO.setUpdatedTime(new Date());
            riskMonitoringInfoDO.setCounty(country);
            riskMonitoringInfoDO.setCreatedTime(new Date());
            riskMonitoringInfoDOList.add(riskMonitoringInfoDO);
            //湿度
            riskMonitoringInfoDO = new RiskMonitoringInfoDO();
            riskMonitoringInfoDO.setRiskType(5);
            riskMonitoringInfoDO.setDesDate(new Date(day.getLong("datetimeEpoch") * 1000));
            riskMonitoringInfoDO.setResult(String.format("%.1f", day.getDouble("humidity") / 100));
            riskMonitoringInfoDO.setCreatedBy("system");
            riskMonitoringInfoDO.setUpdatedBy("system");
            riskMonitoringInfoDO.setUpdatedTime(new Date());
            riskMonitoringInfoDO.setCounty(country);
            riskMonitoringInfoDO.setCreatedTime(new Date());
            riskMonitoringInfoDOList.add(riskMonitoringInfoDO);
            //风力
            riskMonitoringInfoDO = new RiskMonitoringInfoDO();
            riskMonitoringInfoDO.setRiskType(6);
            riskMonitoringInfoDO.setDesDate(new Date(day.getLong("datetimeEpoch") * 1000));
            riskMonitoringInfoDO.setResult(String.format("%.1f", day.getDouble("windspeed") / 3.6));
            riskMonitoringInfoDO.setCreatedBy("system");
            riskMonitoringInfoDO.setUpdatedBy("system");
            riskMonitoringInfoDO.setCounty(country);
            riskMonitoringInfoDO.setUpdatedTime(new Date());
            riskMonitoringInfoDO.setCreatedTime(new Date());
            riskMonitoringInfoDOList.add(riskMonitoringInfoDO);
            //降水
            riskMonitoringInfoDO = new RiskMonitoringInfoDO();
            riskMonitoringInfoDO.setRiskType(7);
            riskMonitoringInfoDO.setDesDate(new Date(day.getLong("datetimeEpoch") * 1000));
            riskMonitoringInfoDO.setResult(String.valueOf(day.getDouble("precip")));
            riskMonitoringInfoDO.setCreatedBy("system");
            riskMonitoringInfoDO.setUpdatedBy("system");
            riskMonitoringInfoDO.setCounty(country);
            riskMonitoringInfoDO.setUpdatedTime(new Date());
            riskMonitoringInfoDO.setCreatedTime(new Date());
            riskMonitoringInfoDOList.add(riskMonitoringInfoDO);
            //风向
            riskMonitoringInfoDO = new RiskMonitoringInfoDO();
            riskMonitoringInfoDO.setRiskType(8);
            riskMonitoringInfoDO.setDesDate(new Date(day.getLong("datetimeEpoch") * 1000));
            riskMonitoringInfoDO.setResult(convertWindDirection(day.getDouble("winddir")));
            riskMonitoringInfoDO.setCreatedBy("system");
            riskMonitoringInfoDO.setUpdatedBy("system");
            riskMonitoringInfoDO.setUpdatedTime(new Date());
            riskMonitoringInfoDO.setCounty(country);
            riskMonitoringInfoDO.setCreatedTime(new Date());
            riskMonitoringInfoDOList.add(riskMonitoringInfoDO);
            JSONArray hours = day.getJSONArray("hours");
            hours.forEach(hour -> {
                WeatherInfoDO weatherInfoDO = new WeatherInfoDO();
                JSONObject hourObj = (JSONObject) hour;
                weatherInfoDO.setFireId(fireId);
                weatherInfoDO.setRecordTime(new Date(hourObj.getLong("datetimeEpoch") * 1000));
                weatherInfoDO.setTemperature(String.valueOf(hourObj.getDouble("temp")));
                weatherInfoDO.setWindLevel(String.format("%.1f", hourObj.getDouble("windspeed") / 3.6));
                weatherInfoDO.setWindDirection(convertWindDirection(hourObj.getDouble("winddir")));
                weatherInfoDO.setPressure(String.valueOf(hourObj.getDouble("pressure")));
                weatherInfoDO.setHumidity(String.format("%.1f", hourObj.getDouble("humidity") / 100));
                //海拔先不改
                weatherInfoDO.setAltitude("15");
                weatherInfoDO.setRainfallRate(String.valueOf(hourObj.getDouble("precip")));
                weatherInfoDO.setCounty(country);
                weatherInfoDO.setDeleted(0);
                weatherInfoDO.setCreatedBy("system");
                weatherInfoDO.setUpdatedBy("system");
                weatherInfoDO.setUpdatedTime(new Date());
                weatherInfoDO.setCreatedTime(new Date());
                weatherList.add(weatherInfoDO);
            });
        }
        weatherInfoDAO.saveBatch(weatherList);
        System.out.println("成功保存weatherInfoDAO" + weatherList.size() + "条数据。");
        riskMonitoringInfoDAO.saveBatch(riskMonitoringInfoDOList);
        System.out.println("成功保存riskMonitoringInfoDAO" + riskMonitoringInfoDOList.size() + "条数据。");
    }

    public void parseDayly(String path) {
        // 读取JSON文件
        String jsonStr = FileUtil.readString(new File(path), StandardCharsets.UTF_8);

        // 解析JSON
        JSONObject json = JSONUtil.parseObj(jsonStr);
        List<JSONObject> days = json.getJSONArray("days").toList(JSONObject.class);

        List<WeatherInfoDO> weatherList = new ArrayList<>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

        for (JSONObject day : days) {
            WeatherInfoDO info = new WeatherInfoDO();

            // 核心字段映射
            info.setTemperature(String.valueOf(day.getDouble("temp")));
            info.setWindLevel(String.valueOf(day.getDouble("windspeed")));
            info.setWindDirection(convertWindDirection(day.getDouble("winddir")));
            info.setPressure(String.valueOf(day.getDouble("pressure")));
            info.setHumidity(String.valueOf(day.getDouble("humidity")));
            info.setRainfallRate(String.valueOf(day.getDouble("precip")));

            // 时间处理
            try {
                Date recordDate = sdf.parse(day.getStr("datetime"));
                info.setRecordTime(recordDate);
            } catch (Exception e) {
                e.printStackTrace();
            }

            // 其他字段（根据业务补充）
            info.setFireId(1); // 示例火情ID
            info.setCounty("未知县"); // 需要根据坐标反查地理信息

            weatherList.add(info);
        }
        weatherInfoDAO.saveBatch(weatherList);
    }

    public static String convertWindDirection(double windDirection) {
        // 确保角度在 0-360 范围内
        windDirection = windDirection % 360;
        if (windDirection < 0) {
            windDirection += 360;
        }

        // 获取方位名称
        String directionName = getDirectionName(windDirection);

        // 格式化输出
        return String.format("%.0fº(%s)", windDirection, directionName);
    }

    /**
     * 根据风向值获取方位名称（8方位）
     *
     * @param windDirection 风向值（0-360度）
     * @return 方位名称，如 "东南"
     */
    private static String getDirectionName(double windDirection) {
        if (windDirection >= 337.5 || windDirection < 22.5) {
            return "北";
        } else if (windDirection >= 22.5 && windDirection < 67.5) {
            return "东北";
        } else if (windDirection >= 67.5 && windDirection < 112.5) {
            return "东";
        } else if (windDirection >= 112.5 && windDirection < 157.5) {
            return "东南";
        } else if (windDirection >= 157.5 && windDirection < 202.5) {
            return "南";
        } else if (windDirection >= 202.5 && windDirection < 247.5) {
            return "西南";
        } else if (windDirection >= 247.5 && windDirection < 292.5) {
            return "西";
        } else {
            return "西北";
        }
    }
}
